package com.ygqh.baby.handler;

import com.alibaba.fastjson.JSON;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.model.*;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.PlatformUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

/**
 * 〈〉
 *
 * @author guohao
 * @date 2019/5/6 13:58
 * @since 1.0.0
 */
@Component
public class SaveMainOrderHandler {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private CarPromotionHandler carPromotionHandler;
    @Autowired
    private YgUserAddressService ygUserAddressService;
    @Autowired
    private YgFrameCodeService ygFrameCodeService;
    @Autowired
    private YgPlatformService ygPlatformService;
    @Autowired
    private YgSalesPromotionService ygSalesPromotionService;
    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private YgOrderLogService ygOrderLogService;
    @Autowired
    private YgOrderDetailService ygOrderDetailService;
    @Autowired
    private YgStockService ygStockService;
    @Autowired
    private YgUserBalanceService ygUserBalanceService;
    @Autowired
    private YgShoppingCarService ygShoppingCarService;
    @Autowired
    private YgCouponDetailService ygCouponDetailService;
    @Autowired
    private YgCouponService ygCouponService;
    @Autowired
    private YgCardCouponDetailService ygCardCouponDetailService;
    @Autowired
    private YgSkuService ygSkuService;
    @Autowired
    private YgUserService ygUserService;

    public Message saveMainOrder(SaveMainOrderParam saveMainOrderParam) {
        SaveMainOrderBo saveMainOrderBo = buildOrder(saveMainOrderParam);

        return saveMainOrder(saveMainOrderBo);
    }

    public SaveMainOrderBo buildOrder(SaveMainOrderParam saveMainOrderParam) {

        List<ShoppingCarBasicData> carBasicDataList = carPromotionHandler.getCarBasicDataList(saveMainOrderParam.getUserId(),
                saveMainOrderParam.getSalesPlatform(), saveMainOrderParam.getSkuList());
        List<CarPromotionWrapper> carPromotionWrapperList =
                carPromotionHandler.getCarListWithPromotion(carBasicDataList, saveMainOrderParam.isDistribution(),
                        saveMainOrderParam.getPlatformNo());

        if (saveMainOrderParam.getCouponDetailId() != null) {
            YgCoupon coupon = ygCouponService.findByDetailId(saveMainOrderParam.getCouponDetailId());

            for (CarPromotionWrapper wrapper : carPromotionWrapperList) {
                if (coupon != null && CollectionUtils.isNotEmpty(coupon.getRelateIdList())) {
                    List<Long> relateIdList = coupon.getRelateIdList();
                    Long relateId;
                    if (SceneType.Product.equals(coupon.getSceneType())) {
                        relateId = wrapper.getCarBasicData().getProductId();
                    } else if (SceneType.Brand.equals(coupon.getSceneType())) {
                        relateId = wrapper.getCarBasicData().getBrandId();
                    } else {
                        continue;
                    }
                    if (relateIdList.contains(relateId)) {
                        wrapper.setUserCoupon(true);
                    }
                } else {
                    wrapper.setUserCoupon(true);
                }
            }
        }


        YgOrder order = new YgOrder();
        // 设置收货信息
        YgUserAddress address = ygUserAddressService.findById(saveMainOrderParam.getAddressId(), saveMainOrderParam.getUserId());
        setUserAddress(order, address);
        order.setUserRemark(saveMainOrderParam.getUserRemark());
        order.setPostCode(address.getIdentityNo());
        // 保存主单
        order.setCouponDetailId(saveMainOrderParam.getCouponDetailId());
        Long orderId = ygFrameCodeService.getFrameCode(CodeType.Order, new Date());

        order.setOrderId(orderId);
        order.setParentId(orderId);
        order.setUserId(saveMainOrderParam.getUserId());
        order.setTotalPrice(saveMainOrderParam.getTotalPrice());

        CarPricesResult carPricesResult = CarApportionPriceHandler.calculateCarDisPrice(carPromotionWrapperList);
        CarApportionPriceHandler.apportionMjAndCouponAndExpressAndAccountPrice(carPromotionWrapperList, saveMainOrderParam.getManjinPrice(),
                saveMainOrderParam.getYhqPrice(), saveMainOrderParam.getExpressPrice(), saveMainOrderParam.getAccountPrice());

        order.setProductPrice(carPricesResult.getProductPrice());
        order.setExpressPrice(saveMainOrderParam.getExpressPrice());
        order.setManjianPrice(saveMainOrderParam.getManjinPrice());
        order.setYouhuijuanPrice(saveMainOrderParam.getYhqPrice());
        order.setNewCustomDisPrice(carPricesResult.getNewCustomDisPrice());
        order.setPackDisPrice(carPricesResult.getPackDisPrice());
        order.setBmdisPrice(carPricesResult.getBmdisPrice());
        order.setVipDisPrice(carPricesResult.getVipDisPrice());
        order.setPayType(saveMainOrderParam.getPayType());
        order.setSupplierId(null);
        order.setOrderStatus(OrderStatus.WaitingPay);
        order.setCreateTime(new Date());
        order.setSourceCode(saveMainOrderParam.getSourceCode());
        order.setAccountPrice(saveMainOrderParam.getAccountPrice());
        order.setFormId(saveMainOrderParam.getFormId());
        order.setOrderType(saveMainOrderParam.getOrderType());
        order.setReleationId(saveMainOrderParam.getReleationId());
        order.setExpressCompany(carPricesResult.getSpecialPrice().toString());
        order.setUserName(saveMainOrderParam.getUserName());

        YgPlatform platform = ygPlatformService.findByPlatformNo(saveMainOrderParam.getPlatformNo());
        if (platform != null) {
            order.setPlatformNo(saveMainOrderParam.getPlatformNo());
            order.setPlatformName(platform.getName());
        }
        AppType appType = AppType.WeChat;
        if (StringUtils.isNotBlank(saveMainOrderParam.getFormId())) {
            appType = AppType.Small;
        }
        order.setAppType(appType);
        List<YgStock> stocks = new ArrayList<YgStock>();

        List<YgOrderDetail> detailList = new ArrayList<YgOrderDetail>();
        for (CarPromotionWrapper carPromotionWrapper : carPromotionWrapperList) {
            ShoppingCarBasicData carBasicData = carPromotionWrapper.getCarBasicData();
            ShoppingCarDisPrice carDisPrice = carPromotionWrapper.getCarDisPrice();
            YgOrderDetail detail = new YgOrderDetail();
            detail.setOrderId(orderId);
            detail.setProductId(carBasicData.getProductId());
            detail.setProductCode(carBasicData.getProductCode());
            detail.setProductName(carBasicData.getProductName());
            detail.setPromotionType(carBasicData.getSalesType());
            detail.setQuantity(carBasicData.getQuantity());
            detail.setSize(carBasicData.getSizeName());
            detail.setSupplierId(carBasicData.getSupplierId());
            detail.setSkuCode(carBasicData.getSkuCode());
            detail.setSkuId(carBasicData.getSkuId());
            detail.setUnitName(carBasicData.getUnitName());
            detail.setImageUrl(carBasicData.getImagePath());
            detail.setShortName(carBasicData.getColor());

            detail.setSalePrice(carBasicData.getSalesPrice());
            detail.setMjDisPrice(carDisPrice.getManjianDisPrice());
            detail.setYhqDisPrice(carDisPrice.getYhqDisPrice());
            detail.setBmDisPrice(carDisPrice.getBmdismDisPrice());
            detail.setPackDisPrice(carDisPrice.getPackDisPrice());
            detail.setNewCustomDisPrice(carDisPrice.getNewCustomDisPrice());
            detail.setVipDisPrice(carDisPrice.getVipDisPrice());
            detail.setExpressPrice(carDisPrice.getExpressPrice());
            detail.setAccountPrice(carDisPrice.getAccountDisPrice());

            detail.setCostPrice(carBasicData.getCostPrice());

            //该条明细应付
            BigDecimal realPrice = carDisPrice.getProductPrice().subtract(carDisPrice.getTotalDisPrice())
                    .add(carDisPrice.getExpressPrice());
            detail.setRealPrice(realPrice);

            detail.setShareRate(carBasicData.getShareRate());
            detail.setForeverRate(carBasicData.getForeverRate());

            //设置促销信息
            setPromotionRemark(carPromotionWrapper, detail);
            //兼容老版本退货，后期可去掉 TODO
            setRemark(order, detail, carPromotionWrapper);
            detailList.add(detail);

            YgStock stock = new YgStock();
            stock.setSkuCode(carBasicData.getSkuCode());
            stock.setAmount(carBasicData.getQuantity());
            stocks.add(stock);
        }

        ygSalesPromotionService.activityForSingleGift(detailList, stocks, saveMainOrderParam.getSourceCode(), saveMainOrderParam.getTotalPrice(),
                saveMainOrderParam.getUserName(), saveMainOrderParam.getOrderType());
        SaveMainOrderBo saveMainOrderBo = new SaveMainOrderBo();
        saveMainOrderBo.setOrder(order);
        saveMainOrderBo.setSalesPlatform(saveMainOrderParam.getSalesPlatform());
        saveMainOrderBo.setOrderDetailList(detailList);
        saveMainOrderBo.setStockList(stocks);
        return saveMainOrderBo;
    }

    public SaveMainOrderBo buildOrderBySku(SaveOrderBySkuParam param) {

        YgOrder order = new YgOrder();
        // 设置收货信息
        YgUserAddress address = ygUserAddressService.findById(param.getAddressId(), param.getUserId());
        setUserAddress(order, address);
        order.setPostCode(address.getIdentityNo());
        // 保存主单
        Long orderId = ygFrameCodeService.getFrameCode(CodeType.Order, new Date());
        order.setOrderId(orderId);
        order.setParentId(orderId);
        order.setUserId(param.getUserId());
        order.setTotalPrice(param.getTotalPrice());

        order.setProductPrice(param.getProductPrice());
        order.setExpressPrice(param.getExpressPrice());
        order.setManjianPrice(BigDecimal.ZERO);
        order.setYouhuijuanPrice(BigDecimal.ZERO);
        order.setNewCustomDisPrice(BigDecimal.ZERO);
        order.setPackDisPrice(BigDecimal.ZERO);
        order.setBmdisPrice(BigDecimal.ZERO);
        order.setVipDisPrice(BigDecimal.ZERO);
        order.setPayType(PayType.WeChat);
        order.setOrderStatus(param.getOrderStatus());
        order.setCreateTime(new Date());
        order.setAccountPrice(param.getAccountPrice());
        order.setOrderType(param.getOrderType());
        order.setReleationId(param.getReleationId());

        YgUser user = ygUserService.findById(param.getUserId());
        order.setUserName(user.getUserName());

        YgPlatform platform = ygPlatformService.findByPlatformNo(param.getPlatformNo());
        order.setPlatformNo(param.getPlatformNo());
        if (platform != null) {
            order.setPlatformName(platform.getName());
        }

        order.setAppType(param.getAppType());
        List<YgOrderDetail> orderDetailList = new ArrayList<>();
        List<YgStock> stockList = new ArrayList<>();

        for (SaveOrderBySkuDetailParam detailParam : param.getDetailList()) {
            SkuBasicData skuBasicData = ygSkuService.getBasicDataBySkuId(detailParam.getSkuId());
            YgOrderDetail detail = new YgOrderDetail();
            detail.setOrderId(orderId);
            detail.setProductId(skuBasicData.getProductId());
            detail.setProductCode(skuBasicData.getProductCode());
            detail.setProductName(skuBasicData.getProductName());
            detail.setPromotionType(PromotionType.Ordinary);
            detail.setQuantity(detailParam.getQuantity());
            detail.setSize(skuBasicData.getSizeName());
            detail.setSupplierId(skuBasicData.getSupplierId());
            detail.setSkuCode(skuBasicData.getSkuCode());
            detail.setSkuId(skuBasicData.getSkuId());
            detail.setUnitName(skuBasicData.getUnitName());
            detail.setImageUrl(skuBasicData.getMainImageUrl());
            detail.setShortName(skuBasicData.getColor());

            detail.setSalePrice(detailParam.getSalePrice());
            detail.setMjDisPrice(BigDecimal.ZERO);
            detail.setYhqDisPrice(BigDecimal.ZERO);
            detail.setBmDisPrice(BigDecimal.ZERO);
            detail.setPackDisPrice(BigDecimal.ZERO);
            detail.setNewCustomDisPrice(BigDecimal.ZERO);
            detail.setVipDisPrice(BigDecimal.ZERO);
            detail.setExpressPrice(BigDecimal.ZERO);
            detail.setAccountPrice(BigDecimal.ZERO);
            detail.setCostPrice(skuBasicData.getCostPrice());

            //该条明细应付
            detail.setRealPrice(detailParam.getRealPrice());
            detail.setShareRate(skuBasicData.getShareRate());
            detail.setForeverRate(skuBasicData.getForeverRate());

            //设置促销信息
            PromotionBo promotionBo = new PromotionBo();
            promotionBo.setType(detailParam.getPromotionType());
            promotionBo.setSpecial(false);
            promotionBo.setSpecialPrice(BigDecimal.ZERO);

            detail.setPromotionRemark(JSON.toJSONString(promotionBo));

            orderDetailList.add(detail);

            YgStock stock = new YgStock();
            stock.setSkuCode(skuBasicData.getSkuCode());
            stock.setAmount(detailParam.getQuantity());
            stockList.add(stock);
        }

        apportionedExpress(param.getExpressPrice(), param.getProductPrice(), orderDetailList);
        apportionedAccountPrice(param.getAccountPrice(), param.getProductPrice().add(param.getExpressPrice()), orderDetailList);
        resetRealPrice(orderDetailList);

        SaveMainOrderBo saveMainOrderBo = new SaveMainOrderBo();
        saveMainOrderBo.setOrder(order);
        saveMainOrderBo.setSalesPlatform(PlatformUtil.converte(param.getPlatformNo()));
        saveMainOrderBo.setOrderDetailList(orderDetailList);
        saveMainOrderBo.setStockList(stockList);
        return saveMainOrderBo;
    }

    private void resetRealPrice(List<YgOrderDetail> orderDetailList) {
        orderDetailList.forEach(detail -> {
            BigDecimal totalDisPrice = detail.getPackDisPrice().add(detail.getNewCustomDisPrice()).add(detail.getVipDisPrice()).add(detail.getBmDisPrice())
                    .add(detail.getMjDisPrice()).add(detail.getYhqDisPrice()).add(detail.getAccountPrice());
            BigDecimal realPrice = detail.getSalePrice().multiply(new BigDecimal(detail.getQuantity())).subtract(totalDisPrice).add(detail.getExpressPrice());
            detail.setRealPrice(realPrice);
        });
    }

    private void setUserAddress(YgOrder order, YgUserAddress address) {
        // 设置收货信息
        order.setReceiver(address.getReceiver());
        order.setProvinceName(address.getProvinceName());
        order.setCityName(address.getCityName());
        order.setAreaName(address.getAreaName());
        order.setAddress(address.getAddress());
        order.setTelPhone(address.getTelPhone());

    }

    private void apportionedExpress(BigDecimal expressPrice, BigDecimal priceForApportion, List<YgOrderDetail> orderDetailList) {
        if (expressPrice.compareTo(BigDecimal.ZERO) == 0) {
            return;
        }

        BigDecimal lastExpressPrice = expressPrice;
        for (int i = 0; i < orderDetailList.size(); i++) {
            YgOrderDetail orderDetail = orderDetailList.get(i);
            if (i == orderDetailList.size() - 1) {
                orderDetail.setExpressPrice(lastExpressPrice);
                break;
            }
            BigDecimal apportionedExpress = expressPrice.divide(priceForApportion, 2, BigDecimal.ROUND_HALF_DOWN).multiply(priceForApportion);
            orderDetail.setExpressPrice(apportionedExpress);
            lastExpressPrice = lastExpressPrice.subtract(apportionedExpress);
        }
    }

    private void apportionedAccountPrice(BigDecimal accountPrice, BigDecimal priceForApportion, List<YgOrderDetail> orderDetailList) {
        if (accountPrice.compareTo(BigDecimal.ZERO) == 0) {
            return;
        }

        BigDecimal lastAccountPrice = accountPrice;
        for (int i = 0; i < orderDetailList.size(); i++) {
            YgOrderDetail orderDetail = orderDetailList.get(i);
            if (i == orderDetailList.size() - 1) {
                orderDetail.setAccountPrice(lastAccountPrice);
                break;
            }
            BigDecimal apportionedExpress = accountPrice.divide(priceForApportion, 2, BigDecimal.ROUND_HALF_DOWN).multiply(priceForApportion);
            orderDetail.setAccountPrice(apportionedExpress);
            lastAccountPrice = lastAccountPrice.subtract(apportionedExpress);
        }
    }

    private void setPromotionRemark(CarPromotionWrapper carPromotionWrapper, YgOrderDetail detail) {
        PromotionBo promotionBo = new PromotionBo();
        PromotionType promotionType = carPromotionWrapper.getCarBasicData().getSalesType();
        promotionBo.setSpecial(carPromotionWrapper.getCarBasicData().isSpecial());
        promotionBo.setType(promotionType);
        promotionBo.setId(carPromotionWrapper.getPromotionId());
        promotionBo.setSpecialPrice(carPromotionWrapper.getCarDisPrice().getSpecialPrice());
        if (PromotionType.Bmdism.equals(promotionType)) {
            BmdismLadderModel.BmdismLadder bestLadder = carPromotionWrapper.getBestLadder();
            promotionBo.setBuyCount(bestLadder.getBuyCount());
            promotionBo.setDisCount(bestLadder.getDisCount());
        }
        if (PromotionType.Pack.equals(promotionType)) {
            YgProductPack productPack = carPromotionWrapper.getProductPack();
            promotionBo.setPackAmount(carPromotionWrapper.getPackAmount());
            promotionBo.setBuyCount(productPack.getProductAmount().intValue());
            promotionBo.setPackPrice(productPack.getPackPrice());
            promotionBo.setCumulative(productPack.getCumulative());
            promotionBo.setUseCoupon(productPack.getUseCoupon());
        }
        if (PromotionType.ManZeng.equals(promotionType) || PromotionType.JiaJiaGou.equals(promotionType)) {
            promotionBo.setLimitPrice(carPromotionWrapper.getLimitPrice());
        }
        detail.setPromotionRemark(JSON.toJSONString(promotionBo));

    }

    public Message saveMainOrder(SaveMainOrderBo saveMainOrderBo) {
        int row = 0;
        YgOrder order = saveMainOrderBo.getOrder();
        List<YgOrderDetail> orderDetailList = saveMainOrderBo.getOrderDetailList();
        List<YgStock> stockList = saveMainOrderBo.getStockList();
        boolean reduceStockFlag = saveMainOrderBo.isReduceStockFlag();
        Long expressCardId = saveMainOrderBo.getExpressCardId();
        try {
            row = ygOrderService.save(order);
            ygOrderLogService.addOrderLog(order.getOrderId(), order.getOrderStatus(), order.getUserName(), "主订单保存成功 ;order=" + order.toString());
            logger.info("主单保存成功。orderId =" + order.getOrderId());
        } catch (Exception e) {
            e.printStackTrace();
            ygOrderLogService.addOrderLog(order.getOrderId(), order.getOrderStatus(), order.getUserName(), "主订单保存失败;order=" + order.toString());
            logger.error("主单保存失败。orderInfo:" + order.toString());
            return Message.error("提交订单失败！", order.getOrderId());
        }
        if (row > 0) {

            ygOrderDetailService.addBatch(orderDetailList);
            if (reduceStockFlag) {
                // 扣减库存
                ygStockService.reduceStock(stockList, "saveMainOrder");
            }
            // 扣减虚拟账户金额
            if (order.getAccountPrice().compareTo(new BigDecimal(0)) > 0) {
                int i = ygUserBalanceService.reduceAcountPrice(order.getUserId(), order.getAccountPrice());
                if (i > 0 && order.getAccountPrice().compareTo(BigDecimal.ZERO) > 0) {
                    // 扣减成功在，生成一条流水
                    ygUserBalanceService.addBalanceDetail(order.getUserId(), order.getOrderId().toString(), order.getAccountPrice().multiply(new BigDecimal(-1)),
                            BalanceType.Balance, OperationType.PayOrder, "支付订单", order.getPlatformNo());
                }
            }
            // 删除购物车
            ygShoppingCarService.deleteCarByCheck(order.getUserId(), saveMainOrderBo.getSalesPlatform());
            // 把当前使用的优惠券消费掉
            if (order.getCouponDetailId() != null) {
                YgCouponDetail couponDetail = new YgCouponDetail();
                couponDetail.setId(order.getCouponDetailId());
                couponDetail.setUseStatus(CouponStatus.Used);
                couponDetail.setUseTime(new Date());
                ygCouponDetailService.update(couponDetail);
            }
            // 更新包邮卡使用状态
            if (expressCardId != null) {
                YgCardCouponDetail updateRecord = new YgCardCouponDetail();
                updateRecord.setId(expressCardId);
                updateRecord.setUseStatus(UseStatus.Used);
                updateRecord.setUseTime(new Date());
                updateRecord.setRelationId(order.getOrderId());
                ygCardCouponDetailService.update(updateRecord);
            }
        }
        Map<String, Long> map = new HashMap<>();
        map.put("orderId", order.getOrderId());
        map.put("groupBuyId", order.getReleationId());
        return Message.success(map);
    }

    private void setRemark(YgOrder order, YgOrderDetail detail, CarPromotionWrapper carPromotionWrapper) {
        ShoppingCarBasicData carModel = carPromotionWrapper.getCarBasicData();
        if (carModel.getSalesType().equals(PromotionType.ManZeng)) {
            detail.setSalePrice(new BigDecimal(0));
            detail.setRemark(PromotionType.ManZeng + "," + carPromotionWrapper.getLimitPrice().toString());
        }
        if (carModel.getNewCustomPrice() != null && carModel.getNewCustomPrice().compareTo(new BigDecimal(0)) > 0) {
            detail.setRemark(PromotionType.NewCustom + "," + carModel.getNewCustomPrice().toString());
        }
        if (carModel.getSalesType().equals(PromotionType.Bmdism)) {
            detail.setRemark(PromotionType.Bmdism + "," + carPromotionWrapper.getPromotionId() + "," + carModel.getRealSalesPrice());
        }
        if (carModel.getSalesType().equals(PromotionType.Pack)) {
            StringBuilder remark = new StringBuilder();
            remark.append(PromotionType.Pack).append(",").append(carPromotionWrapper.getProductPack().getPackPrice()).append(",")
                    .append(carPromotionWrapper.getProductPack().getProductAmount()).append(",").append(carPromotionWrapper.getPromotionId()).append(",")
                    .append(carPromotionWrapper.getProductPack().getProductAmount()).append(",").append(carPromotionWrapper.getProductPack().getUseCoupon());

            detail.setRemark(remark.toString());
            if (!Constant.YIJIADIAN_PLATFORM_NO.equals(order.getPlatformNo())) {
                detail.setShareRate(new BigDecimal("0.05"));
            }
        }
    }

}
